package xin.marcher.wind.migrate.component.lock;

import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 滚动加锁服务对象
 */
public class ScrollLock {

    /**
     * 加锁对象集合
     */
    List<Scroll> scrollList = new ArrayList<>();

    /**
     * 针对一个库的一个表的滚动处理进行加锁
     *
     * @param tableName 表名
     * @return 加锁结果
     */
    public boolean lock(String tableName, String domain) {
        // 判断是否已经加锁, 是则直接返回
        for (Scroll scroll : scrollList) {
            if (scroll.getTableName().equals(tableName) && scroll.getDomain().equals(domain)) {
                return scroll.getLock().tryLock();
            }
        }

        // 加锁
        synchronized (ScrollLock.class) {
            for (Scroll scroll : scrollList) {
                if (scroll.getTableName().equals(tableName) && scroll.getDomain().equals(domain)) {
                    return scroll.getLock().tryLock();
                }
            }

            Scroll newScroll = new Scroll();
            newScroll.setTableName(tableName);
            newScroll.setDomain(domain);
            scrollList.add(newScroll);
            return newScroll.getLock().tryLock();
        }
    }

    /**
     * 解锁
     *
     * @param tableName 表名
     */
    public void unlock(String tableName, String domain) {
        for (Scroll scroll : scrollList) {
            if (scroll.getTableName().equals(tableName) && scroll.getDomain().equals(domain)) {
                scroll.getLock().unlock();
            }
        }
    }

    /**
     * 锁对象
     */
    @Data
    static class Scroll {

        /**
         * 系统对象
         */
        private String domain;

        /**
         * 表名
         */
        private String tableName;

        /**
         * 锁
         */
        private Lock lock = new ReentrantLock(false);
    }
}
